import pygame
from didiball.sprites.ActiveSprite import ActiveSprite
from didiball.sprites.SpriteSheetSurface import SpriteSheetSurface
import didiball.Physics2D as p2d    

class Team():
    max_speed = 0.4
    acc = 0.0025
    friction = 0.001
    mass = 10
    def __init__(self, r2l, colour, name, path, player_dynamics, formation, positions, pitch, is_ai=False,controls=None,sleeve_colour=(0,0,0),shorts_colour=(0,0,0)):
        self.__r2l = r2l
        self.__colour = colour
        self.__sleeve_colour = sleeve_colour
        self.__shorts_colour = shorts_colour
        self.__name = name
        self.__path = path
        self.__pitch = pitch
        self.__is_ai = is_ai
        self.__score = 0
        self.__active_players = []
        self.__controls = controls
        self.make_players(player_dynamics, formation, positions, pitch)

    def get_controls(self):
        return self.__controls
        
    def is_ai(self):
        return self.__is_ai
    
    def is_ahead(self,subj_xy,obj_xy):
        if(subj_xy[0] > obj_xy[0]):
            return -1 * self.is_r2l()
        else:
            return self.is_r2l()
            
    def find_nearest_inactive_player(self,ball,attacking_multiple=1):
        which=None
        min_dist=None
        for player in self.players:
            if player not in self.__active_players:
                dist = p2d.calc_distance( player.get_pos_xy(), ball.get_pos_xy())
                if self.is_ahead(player.get_pos_xy(),ball.get_pos_xy()):
                    dist_adj= dist / attacking_multiple
                else:
                    dist_adj = dist
                if dist_adj < min_dist or min_dist== None:
                    which=player
                    min_dist= dist_adj
        return which
        
    def select_player(self,player):
        if player:
            player.set_speed_magnitude(0)
            self.set_active_players([player])
        
    #this is for when you select next nearby player
    def select_next_player(self,ball,attack_multiple=1):
        self.select_player(self.find_nearest_inactive_player(ball,attack_multiple))

        #this is now for ai only. choose nearest 
        #(only difference with above is that it will stick to the same player as long as (s)he's closest)
    def choose_players(self,ball):
        which=None
        min_dist=100000000
        for player in self.players:
                dist = p2d.calc_distance( player.get_pos_xy(), ball.get_pos_xy())
                if dist < min_dist:
                        which=player
                        min_dist= dist
        if which:
                self.set_active_players([which])


    def players_do(self,ball,dt):
        x=160
        #non-active players return to base
        for player in self.players:
                if player not in self.__active_players:
                    # if not self.__is_ai:
                        # dist_to_ball = player.calc_distance_to(ball)
                        
                        # #active = self.__active_players[0]
                        # if dist_to_ball < x:
                            # player.move_towards(dt,ball.get_pos_xy())
                            # #print player , ": attack! (", dist_to_ball, ")"
                            # #player.attack(dt,ball)
                        # else:
                            # player.move_towards(dt,player.get_basepoint_adjusted(ball,self.__r2l))
                    # else:
                        player.move_towards(dt,player.get_basepoint_adjusted(ball,self.__r2l))
        if self.__is_ai:
            if self.__active_players != None:
                for player in self.__active_players:
                    player.attack(dt,ball)
                    

    def get_path(self): 
        return self.__path
 
    def refresh_players(self,tick_ms,ball):
        for player in self.players:
            if player not in self.__active_players:
                velocity=0
            else:
                velocity=1
            player.refresh_surface(tick_ms,p2d.calc_angle(player.get_pos_xy(),ball.get_pos_xy()),velocity)
            
    def mod_active_players(self,x,y,dt):
        for player in self.__active_players:
            player.mod(x,y,dt)
            #player.refresh_surface(p2d.calc_angle(player,ball))

    def move_active_player(self,dt):
        for player in self.players:
            player.move(dt,self.__pitch)
#            for i in self.__active_players:
 #               i.move(dt,self.__pitch)
        #self.__radar.blit_item(mvec[0],mvec[1],self.__colour)

    def get_active_players(self):
        return self.__active_players

    def set_active_players(self,active_players):
        self.unhighlight(self.__active_players)
        self.__active_players=active_players
        self.highlight(self.__active_players)
        
    def highlight(self,players):
        for player in players:
            player.highlight()
    def unhighlight(self,players):
        for player in players:
            player.unhighlight()

    def new_player_surface(self,bg):
#	radius=25
#	bgs= pygame.Surface((radius*2,radius*2))
#	bgs.set_alpha(0)
#	fgs= pygame.Surface((radius*2,radius*2))
#	pygame.draw.circle(fgs,self.__colour,(radius,radius),radius)
#	return bgs,fgs
        return pygame.image.load(self.__path).convert_alpha()
    
    def new_player_spritesheet(self):
        sprite_info = {
            'path' : self.__path,
            'size' : (40,40),
            'y-count' : 3,
            'y-stationary' : 1,
            'x-positions': [
                'down','downright','right','upright','up','upleft','left','downleft'
            ], 
            'sprite_skin_colour': (255,99,0), #ff 63 00
            'sprite_hair_colour': (128,0,0), #80 00 00
            'sprite_torso_colour': (255,0,0),
            'sprite_sleeve_colour' : (0,0,255),
            'sprite_shorts_colour' : (255,255,255)
        }
        sprite_sheet = SpriteSheetSurface( sprite_info, self.__colour, self.__sleeve_colour, self.__shorts_colour, self.__pitch.GREEN)
        #sprite_sheet = SpriteSheetSurface( self.__path, size, coords_map, 3, replace_colours) #3 frames
        return sprite_sheet

    def make_players(self, player_dynamics, formation, positions, pitch):
        self.players= []
        self.goalkeepers= []
        self.defenders= []
        self.midfielders= []
        self.attackers= []
        GK=0
        DF=1
        MF=2
        AT=3
        #goalkeepercount,defendercount, midfieldcount, attackercount = formation
        i=0
        for pos in positions[GK]:
                basepoint= pitch.calc_basepoint(self.__r2l,pos,i,len(positions[GK]))
                startpoint= pitch.calc_halfpoint(self.__r2l,pos,i,len(positions[GK]))
                #m= ActiveSprite(player_dynamics,self,basepoint, startpoint,self.new_player_surface(pitch.GREEN),'GK {0}'.format(i+1))
                m= ActiveSprite(player_dynamics,self,basepoint, startpoint,self.new_player_spritesheet(),'GK {0}'.format(i+1))
                i+= 1
                self.players.append( m )
                self.goalkeepers.append( m )
        i=0
        for pos in positions[DF]:
                basepoint= pitch.calc_basepoint(self.__r2l,pos,i,len(positions[DF]))
                startpoint= pitch.calc_halfpoint(self.__r2l,pos,i,len(positions[DF]))
                m= ActiveSprite(player_dynamics,self,basepoint, startpoint,self.new_player_spritesheet(),'DF {0}'.format(i+1))
                i+= 1
#       for i in range(defendercount):
#               m= ActiveSprite(player_dynamics,self,pitch.calc_zone(self.__r2l,1,i,defendercount),self.new_player_surface(pitch.GREEN),'DF{0}'.format(i))
                self.players.append( m )
                self.defenders.append( m )
        i=0
        for pos in positions[MF]:
                basepoint= pitch.calc_basepoint(self.__r2l,pos,i,len(positions[MF]))
                startpoint= pitch.calc_halfpoint(self.__r2l,pos,i,len(positions[MF]))
                m= ActiveSprite(player_dynamics,self,basepoint, startpoint,self.new_player_spritesheet(),'MF {0}'.format(i+1))
                i+= 1
#        for i in range(midfieldcount):
#                m= ActiveSprite(player_dynamics,self,pitch.calc_zone(self.__r2l,2,i,midfieldcount),self.new_player_surface(pitch.GREEN),'MF{0}'.format(i))
                self.players.append( m )
                self.midfielders.append( m )
        
        i=0
        for pos in positions[AT]:
                basepoint= pitch.calc_basepoint(self.__r2l,pos,i,len(positions[AT]))
                startpoint= pitch.calc_halfpoint(self.__r2l,pos,i,len(positions[AT]))
                m= ActiveSprite(player_dynamics,self,basepoint, startpoint,self.new_player_spritesheet(),'AT {0}'.format(i+1))
                i+= 1
#        for i in range(attackercount):
#                m= ActiveSprite(player_dynamics,self,pitch.calc_zone(self.__r2l,3,i,attackercount),self.new_player_surface(pitch.GREEN),'AT{0}'.format(i))
                self.players.append( m )
                self.attackers.append( m )

    #initialize positions ...
    def init(self):
        i=1
        for player in self.players:
                #pos=(self.calc_x(i,player.is_attack()),self.calc_y(i,len(self.players)))
                #player.set_pos_xy( pos )
                player.move_start()
                player.set_speed_magnitude(0)
                i=i+1
        self.set_active_players([self.players[len(self.players)-1]])
    def is_r2l(self):
        return self.__r2l
    def get_name(self):
        return self.__name
    def get_pitch(self):
        return self.__pitch
    def get_colour(self):
        return self.__colour
    def get_score(self):
        return self.__score
            
    def set_colour(self,colour):
        self.__colour = colour
    def set_name(self,name):
        self.__name = name
    def set_score(self,score):
        self.__score = score   
    def inc_score(self):
        self.__score += 1

    def collision(self,ball,dt,is_hoofing,is_passing):
        ret=False
        for player in self.players:
                #yes. returns a function. First occurence in didiball
                reaction = ball.collision(player,dt)
                if reaction:
                    if is_hoofing:
                        player.hoof(ball)
                        self.select_next_player(ball,2)
                    elif is_passing:
                        teammate=self.find_nearest_inactive_player(ball,100)
                        player.pass_to(ball,teammate)
                        self.select_player(teammate)
                    else:
                        reaction()
                    ret=True
        return ret

    def unblit_to(self, screen, bg):
        for player in self.players:
            player.unblit_to_shifting_plane(screen,self.__pitch,bg) #, font1)

    def calc_adjusted_coords(self,screen, coords_map):
        for player in self.players:
            key="{0}/{1}".format(self.is_r2l(),player.get_caption())
            val=player.calc_adjusted_coords(screen,self.__pitch)
            coords_map[key]=val
        return coords_map

    def blit_to( self, screen, font1,font2):
        for player in self.players:
            player.blit_to_shifting_plane(screen,self.__pitch) #, font1)
        #scores
        multip= self.is_r2l()==False and 1 or -1
        top= int(self.__pitch.get_scoreboard().get_rect().top +20)
        fst=font1.render( self.get_name(), 1, self.__colour) #, (0,0,0))
        team_left= screen.get_rect().width/2+((250-fst.get_rect().width/2*multip)*multip)
        fss=font2.render( str(self.get_score()), 1, (255,255,255)) #, (0,0,0))
        score_left= screen.get_rect().width/2+((150-fss.get_rect().width/2)*multip)
        screen.blit( fst, (int(team_left),int(top)))
        screen.blit( fss, (int(score_left),int(top)))

    def __str__(self):
        return str(self.get_name())+": "+str(self.get_score())
